import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:self32/event/inventory_event.dart';
import 'package:self32/event/set_eas_event.dart';
import 'package:self32/socket/socket.dart';
import 'package:self32/widget/model/auth_model.dart';
import 'package:self32/widget/model/person_model.dart';
import 'package:self32/widget/model/result_model.dart';
import '../entity/book_entity.dart';
import '../entity/reader_entity.dart';
import '../event/scan_event.dart';
import '../event/user_id_event.dart';
import '../http/api.dart';
import '../main.dart';
import '../socket/socket_manager.dart';
import '../util/timer_manager.dart';
import '../util/toast_util.dart';
import '../widget/app_bar.dart';
import '../widget/model/borrow_return_model.dart';
import '../widget/model/scan_model.dart';

class Borrow extends StatefulWidget {
  const Borrow({Key? key}) : super(key: key);

  @override
  State<Borrow> createState() => _BorrowState();
}

class _BorrowState extends State<Borrow> {

  BorrowReturnModel model = BorrowReturnModel();
  ResultModel resultModel = ResultModel();

  final List<BookEntity> _bookList = [];


  SocketManager manager = SocketManager();
  var step = 2;
  StreamSubscription? userSubscription;
  StreamSubscription? inventorySubscription;
  StreamSubscription? easSubscription;
  StreamSubscription? scanSubscription;

  @override
  initState() {
    super.initState();

    userSubscription = eventFactory.on<UserIdEvent>().listen((event) {
      _getUser(event.uid,event.psw);
    });

    easSubscription = eventFactory.on<SetEasEvent>().listen((event) {
      if(event.isSuccess!){
        _borrow(event.no);
      }else{
        _setEasFail(event.no);
      }
    });

    scanSubscription = eventFactory.on<ScanEvent>().listen((event) {
      if(event.no == null){
        return;
      }
      var bookNo = event.no;
      var element = _bookList.firstWhereOrNull((element) => element.no == bookNo);
      if(element == null){
        findBook(bookNo).then((value){
          if(value != null){
            if(value.stateValue == 'borrowed'){
              value.state = 2;
            }else{
              value.state = 0;
            }
            value.isScan = true;
            value.force = true;
            value.uid = null;
            _bookList.add(value);
            model.upDataList(_bookList.where((element) => element.isScan == true));
          }
        });
      }
    });

    inventorySubscription = eventFactory.on<InventoryEvent>().listen((event) {
      for(var item in _bookList){
        if(!item.force){
          item.isScan = false;
        }
      }
      if(event.data!=null && event.data!.isNotEmpty){
        if(step == 2){
          setState(() {
            step = 3;
          });
        }

        for(var item in event.data!.toList()){
          if(item.blockData == null){
            continue;
          }
          try{
            var length = int.parse(item.blockData!.substring(0,2));
            var bookNo = item.blockData!.substring(2, length+2);
            var element = _bookList.firstWhereOrNull((element) => element.no == bookNo);
            if(element == null){
              findBook(bookNo).then((value){
                if(value != null){
                  if(value.stateValue == 'borrowed'){
                    value.state = 2;
                  }else{
                    value.state = 0;
                  }
                  value.isScan = true;
                  value.uid = item.uid;
                  _bookList.add(value);
                  model.upDataList(_bookList.where((element) => element.isScan == true));
                }
              });
            }else{
              element.isScan = true;
              model.upDataList(_bookList.where((element) => element.isScan == true));
            }
          }catch(e){
            model.upDataList(_bookList.where((element) => element.isScan == true));
            print(e);
          }
        }
      }else{
        model.upDataList(_bookList.where((element) => element.isScan == true));
      }
    });

    WidgetsBinding.instance.addPostFrameCallback((_){
      timer.startCountDown(CountDownMode.action, (){
        currentTask.clear();
        timer.cancel();
        manager.setMode(Mode.none);
        Get.back();
      });
    });
  }

  _setEasFail(no){
    BookEntity? item = _bookList.firstWhereOrNull((element) => element.no == no);
    if(item != null){
      item.state = -1;
      item.error = '防盗位改写失败';
    }
    _setEas();
  }

  _borrow(no) async {
    var result = await bookBorrow(currentTask.uid,no);
    BookEntity? item = _bookList.firstWhereOrNull((element) => element.no == no);
    if(item != null){
      setState(() {
        if(result.$1 == 200){
          item.state = 1;
          item.readyReturnDate = result.$2.readyReturnDate;
          currentTask.readerEntity!.currentBorrowCount = currentTask.readerEntity!.currentBorrowCount!+1;
        }else{
          item.state = -1;
          item.error = result.$2;
        }
      });
    }
    _setEas();
  }

  _setEas(){
    for(var item in _bookList){
      if(item.uid == null){
        continue;
      }
      if(item.state == 0){
        socketHelper.add(setEas(item.uid, item.no,true));
        return;
      }
    }
    resultModel.setAble();
    // ResultDialog().show(_bookList.where((element) => element.state==1).length,_bookList.where((element) => element.state == -1).length,(){
    //
    // });
  }

  _getUser(uid,psw) async {
    manager.setMode(Mode.none);
    ReaderEntity? reader = await findReader(uid,password: psw);
    if(reader != null && reader.no != null && reader.no!.isNotEmpty){
      if(psw != null &&!reader.validPassword!){
        toastWarn('密码错误');
        currentTask.clear();
        return;
      }
      currentTask.uid = reader.no;
      currentTask.uName = reader.name;
      currentTask.readerEntity = reader;
      setState(() {
        step = 2;
        manager.setModeAndStart(Mode.inventoryHfRfid);
      });
    }else{
      toastWarn('身份未认证');
      currentTask.clear();
    }
  }


  _title(){
    return Container(
        margin: EdgeInsets.only(top: 10.h,left: 13.w,right: 13.w,bottom: 10.h),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            InkWell(
              onTap: (){
                currentTask.clear();
                timer.cancel();
                manager.setMode(Mode.none);
                Get.back();
              },
              child: Image.asset("assets/images/back.png", width: 40.w, fit: BoxFit.fitWidth,),
            ),
            Image.asset("assets/images/borrow_step$step.png",height:20.h,fit: BoxFit.fitHeight,),
            Obx(() => Text("${timer.actionTime.value}",style: TextStyle(color: Colors.white,fontSize: 8.sp),))
          ],
        )
    );
  }


  @override
  void dispose() {
    userSubscription?.cancel();
    userSubscription = null;
    inventorySubscription?.cancel();
    inventorySubscription = null;
    easSubscription?.cancel();
    easSubscription = null;
    scanSubscription?.cancel();
    scanSubscription = null;
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // floatingActionButton:floatButton(),
      // floatingActionButtonLocation:CustomFloatingActionButtonLocation(
      //     FloatingActionButtonLocation.endFloat, 0,-60.h),
      body: Stack(
        children: [
          Container(
              width: double.infinity,
              height: double.infinity,
              decoration: const BoxDecoration(
                image: DecorationImage(
                  fit: BoxFit.fill,
                  image: AssetImage(
                    "assets/images/bg.png",
                  ),
                ),
              ),
              child: Column(
                children: [
                  appBar(),
                  _title(),
                  if(step == 1)...[
                    AuthModel().show()
                  ],
                  if(step == 2)...[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        // PersonModel().show(),
                        ScanModel().show(),
                      ],
                    )
                  ],
                  if(step == 3)...[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        PersonModel().show(),
                        model.show(_bookList,0,() async {
                          manager.setModeAndStart(Mode.none);
                          _bookList.removeWhere((element) => element.isScan == false);
                          _setEas();
                          setState(() {
                            step = 4;
                          });
                        }),
                      ],
                    )
                  ],
                  if(step == 4)...[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        PersonModel().show(),
                        resultModel.show(_bookList,0),
                      ],
                    )
                  ],
                ],
              )
          ),

        ]
      )
    );
  }
}